<!DOCTYPE HTML>
<html>
<head>
    <title>MINIMMORTS HTML5 client</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript" src="js/constants.js"></script>
    <script type="text/javascript" src="js/resources.js"></script>
    <script type="text/javascript" src="js/routines.js"></script>
    <script type="text/javascript" src="js/Camera.js"></script>
    <script type="text/javascript" src="js/Unit.js"></script>
    <script type="text/javascript" src="js/SpriteLoader.js"></script>
    <script type="text/javascript" src="js/Map.js"></script>
    <script type="text/javascript" src="js/Movement.js"></script>
    <script type="text/javascript" src="js/MovementManager.js"></script>
    <script type="text/javascript" src="js/messages.js"></script>
    <script type="text/javascript" src="js/ServerInteraction.js"></script>
    <script type="text/javascript" src="js/Sprite.js"></script>
    <script type="text/javascript" src="js/SpriteMovement.js"></script>
    <script type="text/javascript" src="js/ActionManager.js"></script>
    <script type="text/javascript" src="js/Point.js"></script>
    <script type="text/javascript" src="js/SpriteMovementAnimation.js"></script>
    <script type="text/javascript" src="js/PathCache.js"></script>
    <script type="text/javascript" src="js/Follow.js"></script>
    <script type="text/javascript" src="js/FollowBlinkAnimation.js"></script>
    <style type="text/css" >
    #scr {
        border: 1px solid #000000;
    }
    #login_form {
        background-color: tan;
        z-index: 1;
        position: absolute;
        top: 300px;
        left: 300px;
        visibility: hidden;
    }
    </style>
</head>
<body onunload="disconnect(); return false;">

<script type="text/javascript">

/*********************
 * Создание холстов. *
 *********************/

// Основной холст, который будет показан клиенту.

var scr = document.createElement('canvas');
scr.id = "scr";
scr.width = SCR_W;
scr.height = SCR_H;
scr.oncontextmenu = function() {
    return false;
}
// Добавление обработчиков нажатий клавиш мыши происходит при запуске игры.
document.body.appendChild(scr);

// Холст для рисования карты.

var map_buffer = document.createElement('canvas');
map_buffer.width = SCR_W;
map_buffer.height = SCR_H;

// Холст для рисования игроков.

var units_buffer = document.createElement('canvas');
units_buffer.width = SCR_W;
units_buffer.height = SCR_H;

// Холст для рисования цвета игроков (цветных квадратиков под юнитами).

var unitcolors_buffer = document.createElement('canvas');
unitcolors_buffer.width = SCR_W;
unitcolors_buffer.height = SCR_H;

/*************************
 * Служебные переменные. *
 *************************/

/**
 * Включение дебага протокола обмена данными с сервером.
 */
var DEBUG_PROTOCOL = false;

/**
 * Включение дебага юнитов.
 */
var DEBUG_UNITS = false;

/**
 * Включение дебага движения.
 */
var DEBUG_MOVEMENTS = false;

/**
 * Включение дебага преследования.
 */
var DEBUG_FOLLOW = false;

/**
 * Включение дебага режимов и их изменения.
 */
var DEBUG_MODES = false;

var ENABLE_GC = false;

var MEGAARRAY = new Array();

/**
 * Список юнитов, принадлежащих клиенту.
 */
var self_units_list = new Array();

/**
 * Список юнитов.
 */
var units_list = new Array();

/**
 * Карта.
 */
var map;

/**
 * Сервер.
 */
var server;

/**
 * Камера. В её объекиве находится место, которое будет нарисовано на основном холсте.
 */
var camera;

/**
 * Камера свободна или привязана к своему игроку.
 */
var is_camera_free = false;

/**
 * Номер текущего хода.
 */
var step;

/**
 * Id этого клиента.
 */
var clientId;

/**
 * Выделенные юниты.
 */
var selected_units = new Array();

/**
 * Клетка начала выделения.
 */
var selections_beg;

/**
 * Прямоугольник выделения.
 */
var selection_rect = null;

/**
 * Менеджер движения.
 */
var movementManager = new MovementManager();

/**
 * Менеджер действий.
 */
var actionManager = new ActionManager();

/**
 * Включает плавное движение юнитов.
 */
var smoothMovementEnabled = true;

/**
 * Таймер цикла пинга сервера.
 */
var pingTimer = null;

/**
 * Таймер цикла рисования.
 */
var drawTimer = null;

/**
 * Время начала текущего хода.
 */
var stepBegTime = null;

/**
 * Длительность предыдущего хода в миллисекундах.
 */
var prevStepTime = null;

/**
 * Пинг до сервера.
 */
var ping = null;

/**
 * Время начала первой итерации цикла рисования.
 */
var drawBegTime = null;

/**
 * Текущее количество итераций цикла рисования.
 */
var redraws = 0;
    
/**
 * Кеш путей.
 */
var pathCache = new PathCache();

/**
 * Использовать кеш путей.
 */
var usePathCache = true;

var scrollBarsHovered = {
    left: false,
    top: false,
    right: false,
    bottom: false
}

var camFollowEnabled = false;

var followings = [];

var followingsTimer = null;

var stepEndTime = null;

var syncTimer = null;

var confirmsCache = [];

var idleMode = false;

var freeAnimation = [];

/************
 * Функции. *
 ************/

function scrOnMousedown(e) {
    var x;
    var y;
    if (e.pageX != undefined && e.pageY != undefined) {
        x = e.pageX;
        y = e.pageY;
    } else {
        x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }
    x -= scr.offsetLeft;
    y -= scr.offsetTop;

    //camMove = scrollBarsHovered.top || scrollBarsHovered.bottom || scrollBarsHovered.left || scrollBarsHovered.right;

    if (e.button == 0/* && !camMove*/) {
        selections_beg = {x1: x, y1: y}
        //scr.addEventListener("mousemove", scrOnMousemove, false);
    }
}

function scrOnMouseup(e) {
    var x;
    var y;
    //var camMove = false;
    if (e.pageX != undefined && e.pageY != undefined) {
        x = e.pageX;
        y = e.pageY;
    } else {
        x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }
    x -= scr.offsetLeft;
    y -= scr.offsetTop;

    if (e.button == 0) {
        
        /*
         * Движение камеры при кликах на панельках по бокам экрана.
         */
        /*if (scrollBarsHovered.top) {
            camera.y -= 1 * CELL_H;
        }
        if (scrollBarsHovered.bottom) {
            camera.y += 1 * CELL_H;
        }
        if (scrollBarsHovered.left) {
            camera.x -= 1 * CELL_W;
        }
        if (scrollBarsHovered.right) {
            camera.x += 1 * CELL_W;
        }
        camMove = scrollBarsHovered.top || scrollBarsHovered.bottom || scrollBarsHovered.left || scrollBarsHovered.right;*/
        
        if (true/*!camMove*/) {
            selected_units = new Array();
            selection_rect = createSelectionRect(selections_beg.x1, selections_beg.y1, x, y);

            for (var i = 0; i < self_units_list.length; i++) {
                if (self_units_list[i].j >= selection_rect.beg.j
                        && self_units_list[i].j <= selection_rect.end.j
                        && self_units_list[i].i >= selection_rect.beg.i
                        && self_units_list[i].i <= selection_rect.end.i) {

                    self_units_list[i].selected = true;
                    selected_units.push(self_units_list[i]);
                } else {
                    self_units_list[i].selected = false;
                }
            }
            //scr.removeEventListener("mousemove", scrOnMousemove, false);
            selection_rect = null;
            selections_beg = null;
            
            if (camFollowEnabled && selected_units.length > 0 && !camera.isFollow()) {
                camera.follow(selected_units[0]);
            } else if (camera.isFollow()) {
                camera.unfollow();
            }
        }
    } else if (e.button == 2) {
        var tAxis = camera.reTranslateAxis(x, y);
        var follow = false;
        var i, j, k;
        for (i = 0; i < self_units_list.length; i++) {
            for (j = 0; j < selected_units.length; j++) {
                if (self_units_list[i] != selected_units[j] && self_units_list[i].isInSprite(tAxis.x, tAxis.y)) {
                    for (k = 0; k < selected_units.length; k++) {
                        addFollowing(selected_units[k], self_units_list[i]);
                    }
                    follow = true;
                    break;
                }
            }
        }
        for (i = 0; !follow && i < units_list.length; i++) {
            for (j = 0; j < selected_units.length; j++) {
                if (units_list[i] != selected_units[j] && units_list[i].isInSprite(tAxis.x, tAxis.y)) {
                    for (k = 0; k < selected_units.length; k++) {
                        addFollowing(selected_units[k], units_list[i]);
                    }
                    follow = true;
                    break;
                }
            }
        }
        if (!follow) {
            actionManager.moveSelectedUnits(new Point(Map.getCellJOnMap(tAxis.x), Map.getCellIOnMap(tAxis.y)));
        }
    }
}

function scrOnMousemove(e) {
    var x;
    var y;
    if (e.pageX != undefined && e.pageY != undefined) {
        x = e.pageX;
        y = e.pageY;
    } else {
        x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }
    x -= scr.offsetLeft;
    y -= scr.offsetTop;

    if (selections_beg != null) {
        selection_rect = createSelectionRect(selections_beg.x1, selections_beg.y1, x, y);
    }
    
    if (y >= 0 && y <= 24) {
        clearInterval(scrollBarsHovered.bottomTimer);
        clearInterval(scrollBarsHovered.topTimer);
        scrollBarsHovered.topTimer = setInterval(camMove, camMoveSpeed);
        scrollBarsHovered.top = true;
        scrollBarsHovered.bottom = false;
    } else if (y >= SCR_H - 1 - 24 && y <= SCR_H - 1) {
        clearInterval(scrollBarsHovered.bottomTimer);
        clearInterval(scrollBarsHovered.topTimer);
        scrollBarsHovered.bottomTimer = setInterval(camMove, camMoveSpeed);
        scrollBarsHovered.top = false;
        scrollBarsHovered.bottom = true;
    } else {
        clearInterval(scrollBarsHovered.bottomTimer);
        clearInterval(scrollBarsHovered.topTimer);
        scrollBarsHovered.top = false;
        scrollBarsHovered.bottom = false;
    }
    if (x >= 0 && x <= 24) {
        clearInterval(scrollBarsHovered.rightTimer);
        clearInterval(scrollBarsHovered.leftTimer);
        scrollBarsHovered.leftTimer = setInterval(camMove, camMoveSpeed);
        scrollBarsHovered.left = true;
        scrollBarsHovered.right = false;
    } else if (x >= SCR_W - 1 - 24 && x <= SCR_W - 1) {
        clearInterval(scrollBarsHovered.rightTimer);
        clearInterval(scrollBarsHovered.leftTimer);
        scrollBarsHovered.rightTimer = setInterval(camMove, camMoveSpeed);
        scrollBarsHovered.left = false;
        scrollBarsHovered.right = true;
    } else {
        clearInterval(scrollBarsHovered.rightTimer);
        clearInterval(scrollBarsHovered.leftTimer);
        scrollBarsHovered.left = false;
        scrollBarsHovered.right = false;
    }
}

var camMoveSpeed = 60;
function camMove() {
    if (scrollBarsHovered.top) {
        camera.y -= 1 * CELL_H;
    }
    if (scrollBarsHovered.bottom) {
        camera.y += 1 * CELL_H;
    }
    if (scrollBarsHovered.left) {
        camera.x -= 1 * CELL_W;
    }
    if (scrollBarsHovered.right) {
        camera.x += 1 * CELL_W;
    }
}

</script>

<!-- Форма логина. -->
<div id="login_form">
Login: <input type="text" id="login" value="test"><br>
Password: <input type="password" id="password" value="test"><br>
Server: <input type="text" id="host" value="ws://localhost:8015/"><br>
<input type="button" id="connect_button" value="Connect" onclick="connect(); return false;">
</div>

<br>
<input type="checkbox" id="toggleSmoothMovement" onclick="toggleSmoothMovement();" checked>
<b>Плавное движение</b> (юнит двигается плавно, но при этом, в случае лагов, может отображаться не в том месте, где на самом деле находся)<br>

<br>
<input type="checkbox" id="toggleCamFollow" onclick="toggleCamFollow();">
<b>Слежение за юнитами</b> (камера движется вслед за выделенными юнитами)<br>

<script type="text/javascript">
document.body.onload = function(e) {
    if (/chrome/.test(navigator.userAgent.toLowerCase())) {
        showLoginForm();
    } else {
        alert("Latest version of Chrome required to play.");
    }
}
document.getElementById('toggleSmoothMovement').checked = smoothMovementEnabled;

document.onkeydown = function(event) {
    var events = event || window.event
    if (events.keyCode == 116) {    // F5
        disconnect();
    }
    if (camera != undefined && camera.target == undefined && events.keyCode == 37) {    // left arrow
        camera.x -= 1 * CELL_W;
    }
    if (camera != undefined && camera.target == undefined && events.keyCode == 38) {    // up arrow
        camera.y -= 1 * CELL_H;
    }
    if (camera != undefined && camera.target == undefined && events.keyCode == 39) {    // right arrow
        camera.x += 1 * CELL_W;
    }
    if (camera != undefined && camera.target == undefined && events.keyCode == 40) {    // down arrow
        camera.y += 1 * CELL_H;
    }
}

var _tripleClickTimer = 0;
scr.ondblclick = function(evt) {
    ClearSelection();
    window.clearTimeout(_tripleClickTimer);

    //handle triple click selecting whole paragraph
    scr.onclick = function() {
        ClearSelection();
    };

    _tripleClickTimer = window.setTimeout(function() {
           document.onclick = null; 
    }, 100);
};
scr.onmouseout = function(e) {
    clearInterval(scrollBarsHovered.bottomTimer);
    clearInterval(scrollBarsHovered.topTimer);
    clearInterval(scrollBarsHovered.rightTimer);
    clearInterval(scrollBarsHovered.leftTimer);
    scrollBarsHovered.top = false;
    scrollBarsHovered.bottom = false;
    scrollBarsHovered.left = false;
    scrollBarsHovered.right = false;
}

function ClearSelection() {
    if (window.getSelection)
        window.getSelection().removeAllRanges();
    else if (document.selection)
        document.selection.empty();
}

(function() {
    var hidden, change, vis = {
            hidden: "visibilitychange",
            mozHidden: "mozvisibilitychange",
            webkitHidden: "webkitvisibilitychange",
            msHidden: "msvisibilitychange",
            oHidden: "ovisibilitychange" /* not currently supported */
        };             
    for (var hidden in vis) {
        if (vis.hasOwnProperty(hidden) && hidden in document) {
            change = vis[hidden];
            break;
        }
    }
    if (change)
        document.addEventListener(change, onchange);
    else if (/*@cc_on!@*/false) // IE 9 and lower
        document.onfocusin = document.onfocusout = onchange
    else
        window.onfocus = window.onblur = onchange;

    function onchange (evt) {
        var body = document.body;
        evt = evt || window.event;

        if (evt.type == "focus" || evt.type == "focusin") {
            body.className = "visible";
        } else if (evt.type == "blur" || evt.type == "focusout") {
            body.className = "hidden";
        } else {
            body.className = this[hidden] ? "hidden" : "visible";
        }
        
        if (body.className == "hidden") {
            idleModeOn();
            console.log(step + ": Игра перешла в фоновый режим.");
        } else if (body.className == "visible") {
            idleModeOff();
            console.log(step + ": Игра вышла из фонового режима.");
        }
    }
})();
</script>

</body>
</html>
